package com.zzy.chapter4.service;

import cn.hutool.core.util.StrUtil;
import com.zzy.chapter4.dutychain.AbstractBusinessHandler;
import com.zzy.chapter4.dutychain.CityHandler;
import com.zzy.chapter4.dutychain.HandlerEnum;
import com.zzy.chapter4.pojo.BusinessLaunch;
import com.zzy.chapter4.pojo.UserInfo;
import com.zzy.chapter4.repo.BusinessLaunchRepository;
import com.zzy.chapter4.repo.UserRepository;
import com.zzy.chapter4.ticket.director.DirectorProxy;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Objects;

@Service
@Slf4j
public class UserService {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private BusinessLaunchRepository businessLaunchRepository;

    @Autowired
    private DirectorProxy directorProxy;

    //@Value("${duty.chain}")
    private String handlerType;

    // 责任链业务处理器
    private AbstractBusinessHandler currentHandler;

    // 业务投放类型
    private String currentHandlerType;

    public List<BusinessLaunch> filterBusinessLaunch(String city, String sex, String product) {
        List<BusinessLaunch> launchList = businessLaunchRepository.findAll();
        return Objects.requireNonNull(buildChain()).processHandler(launchList, city, sex, product);
    }

    @SneakyThrows
    private AbstractBusinessHandler buildChain() {
        if (StrUtil.isBlank(handlerType)) {
            return null;
        }
        if (StrUtil.isBlank(currentHandlerType)) {
            this.currentHandlerType = handlerType;
        }
        if (this.currentHandlerType.equals(handlerType) && Objects.nonNull(currentHandler)) {
            return currentHandler;
        } else {
            log.info("dutychain类型发生变化或者初始化，开始构建责任链...");
            // dutychain投放类型发生变化，或者第一次初始化
            synchronized (this) {
                // 哑结点，相当于为链表创建头部节点，不一定会使用
                AbstractBusinessHandler dummyHeadHandler = new CityHandler();
                AbstractBusinessHandler preHandler = dummyHeadHandler;
                // 根据投放类型将不同的处理器放入链表中
                List<String> handlerTypeList = Arrays.asList(handlerType.split(","));
                for (String handlerType : handlerTypeList) {
                    AbstractBusinessHandler handler =
                            (AbstractBusinessHandler) Class.forName(HandlerEnum.valueOf(handlerType).getValue()).newInstance();
                    preHandler.nextHandler = handler;
                    preHandler = handler;
                }
                // 跳过哑结点
                this.currentHandler = dummyHeadHandler.nextHandler;
                this.currentHandlerType = this.handlerType;
                return this.currentHandler;
            }
        }
    }

    public String login(String account, String password) {
        UserInfo userInfo = userRepository.findByUserNameAndUserPassword(account, password);
        if (userInfo == null) {
            return "用户名或密码错误";
        }
        return "登录成功";
    }

    public String register(UserInfo userInfo) {
        if (checkUserExist(userInfo.getUserName())) {
            return "用户已存在";
        }
        userInfo.setCreateDate(new Date());
        userRepository.save(userInfo);
        return "注册成功";
    }

    protected boolean checkUserExist(String userName) {
        UserInfo userInfo = userRepository.findByUserName(userName);
        if (userInfo == null) {
            return false;
        }
        return true;
    }

    /**
     * 创建票据
     * @param type
     * @param productId
     * @param content
     * @param title
     * @param taxId
     * @param bankInfo
     * @return
     */
    public Object createTicket(String type, String productId, String content, String title, String taxId, String bankInfo) {
        return directorProxy.buildTicket(type, productId, content, title, bankInfo, taxId);
    }
}
